package repositories

import (
	"Godzilla/common/convert"
	"Godzilla/common/db"
	"Godzilla/common/mysql"
	"Godzilla/common/responses"
	"Godzilla/enum/fileds"
	"Godzilla/models"
	"errors"
	"math"
	"strconv"
	"time"
)


type RoleRouterManager struct {
	table	string
	db		*db.DB
}

func NewRoleRouterManager() (RoleRouterManager, error){
	db, err := db.NewDB("mysql", db.Dsn())
	if err != nil {
		return RoleRouterManager{}, err
	}
	return RoleRouterManager{
		table: "role_router",
		db:    db,
	}, err
}

func (manager *RoleRouterManager)InsertRoleRouter(roleId int64, routerId int64) (int64, error) {
	var (
		sql  	string
	)
	//TODO 查找是否已经添加过
	roleRouter := &models.RoleRouter{
		ID:       0,
		RoleId:   roleId,
		RouterId: routerId,
		CreateAt: time.Now().Format("2006-01-02 15:04:05"),
		UpdateAt: time.Now().Format("2006-01-02 15:04:05"),
		Status:   fileds.Enable,
	}

	sql = "INSERT INTO " + manager.table + "(role_id, router_id, create_at, update_at, status) VALUES(?, ?, ?, ?, ?)"
	result, errSql := manager.db.PrepareAndExec(sql, roleRouter.RoleId, roleRouter.RouterId, roleRouter.CreateAt, roleRouter.UpdateAt, roleRouter.Status)
	if errSql != nil {
		return 0, errSql
	}
	returnId, err := result.LastInsertId()
	return returnId, err
}


func (manager *RoleRouterManager)SelectRoleRouterById(roleRouterId string) (roleRouter *models.RoleRouter, err error) {
	sql := "SELECT * FROM " + manager.table + " WHERE id = ? LIMIT 1"
	row, errRows := manager.db.Query(sql, roleRouterId)
	if errRows != nil {
		return &models.RoleRouter{}, errRows
	}
	defer row.Close()
	result := mysql.GetResultRow(row)
	if len(result) == 0 {
		return &models.RoleRouter{}, errors.New("记录不存在")
	}
	roleRouter = &models.RoleRouter{}
	convert.DataToStructByTagSql(result, roleRouter)
	return roleRouter, nil
}

func (manager *RoleRouterManager)UpdateRoleRouterById(roleRouterId int64, status int8) error {
	var (
		sql  string
	)

	sql = "UPDATE " + manager.table + " SET status = ? WHERE id = " + strconv.FormatInt(roleRouterId, 10)
	_, err := manager.db.PrepareAndExec(sql, status)
	if err != nil {
		return err
	}
	return nil
}

func (manager *UserRoleManager)DeleteUserRoleById(userRoleId int64) (bool, error) {
	var (
		sql  string
	)

	sql = "DELETE FROM " + manager.table + " WHERE id = ?"
	_, err := manager.db.PrepareAndExec(sql, userRoleId)
	if err != nil {
		return false, err
	}
	return true, nil
}

func (manager *UserRoleManager)SelectUserRoles(where string, page int64, size int64, sort string, filed string) (results responses.Results, err error) {
	var (
		sql 		string
		count		int64
		totalPage   int64
		sizeStr     string
		offset      int64
		offsetStr   string
	)

	count, err = manager.CountUserRoles(where)
	if err != nil{
		return
	}
	if count == 0 {
		results.Total = count
		results.Size = size
		results.Page = page
		results.Lists = make([]interface{}, 0)
		return results, nil
	}


	totalPage = int64(math.Ceil(float64(count) / float64(size)))
	sizeStr = strconv.FormatInt(size, 10)
	offset = (page -1 ) * size
	offsetStr = strconv.FormatInt(offset, 10)


	sql = "SELECT * FROM " + manager.table + " WHERE " + where  + " ORDER BY " + filed + "  " + sort +" LIMIT "+ offsetStr + " , " + sizeStr
	rows, err := manager.db.Query(sql)
	defer rows.Close()
	if err != nil {
		return results, err
	}

	data := mysql.GetResultRows(rows)
	if len(data) == 0 {
		results.Total = count
		results.Page = page
		results.Size = size
		results.TotalPage = totalPage
		results.Lists = make([]interface{}, 0)
		return results, err
	}

	var userRoleArray []*models.UserRole
	for i := 0; i < len(data); i++ {
		userRole := &models.UserRole{}
		convert.DataToStructByTagSql(data[i], userRole)
		userRoleArray = append(userRoleArray, userRole)
	}

	results.Total = count
	results.Page = page
	results.Size = size
	results.TotalPage = totalPage
	results.Lists = userRoleArray
	return
}

func (manager *UserRoleManager)CountUserRoles(where string) (count int64, err error) {
	var (
		sql	string
	)

	sql = "SELECT COUNT(*) FROM " + manager.table + " WHERE " + where
	rows, err := manager.db.Query(sql)
	defer rows.Close()
	if err != nil {
		return 0, err
	}
	if rows.Next() {
		rows.Scan(&count)
	}
	return count, err
}

